﻿namespace AC.ExtendedRenderer.Toolkit.Charting
{
    using ComponentFactory.Krypton.Toolkit;
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Text;
    using System.Windows.Forms;

    public class SlidingScale : UserControl
    {
        private IPalette _palette;
        private PaletteRedirect _paletteRedirect;
        private Color borderColor = Color.Blue;
        private double curValue;
        private int H;
        private int Hm;
        private int largeTicksCount = 5;
        private double largeTicksDistance;
        private int largeTicksLength = 15;
        private Color needleColor = Color.Blue;
        private bool needleKryptonColor;
        private System.Windows.Forms.Orientation orientation;
        private double scaleRange = 100.0;
        private Color shadowColor = Color.Black;
        private bool shadowEnabled = true;
        private int smallTicksCount = 4;
        private double smallTicksDistance;
        private int smallTicksLength = 10;
        private float smallTicksPixels;
        private bool useKryptonBorder;
        private int W;
        private int Wm;

        public SlidingScale()
        {
            this.InitializeComponent();
            base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            base.SetStyle(ControlStyles.ResizeRedraw, true);
            base.SetStyle(ControlStyles.UserPaint, true);
            base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            base.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            base.UpdateStyles();
            if (this._palette != null)
            {
                this._palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
            }
            KryptonManager.GlobalPaletteChanged += new EventHandler(this.OnGlobalPaletteChanged);
            this._palette = KryptonManager.CurrentGlobalPalette;
            this._paletteRedirect = new PaletteRedirect(this._palette);
            this.InitColors();
        }

        private void CalculateLocals()
        {
            this.W = base.ClientRectangle.Width;
            this.H = base.ClientRectangle.Height;
            this.Wm = this.W / 2;
            this.Hm = this.H / 2;
            this.largeTicksDistance = this.scaleRange / ((double) this.largeTicksCount);
            this.smallTicksDistance = this.largeTicksDistance / ((double) (this.smallTicksCount + 1));
            if (this.Orientation == System.Windows.Forms.Orientation.Horizontal)
            {
                this.smallTicksPixels = (float) ((((double) this.W) / this.scaleRange) * this.smallTicksDistance);
            }
            else
            {
                this.smallTicksPixels = (float) ((((double) this.H) / this.scaleRange) * this.smallTicksDistance);
            }
        }

        private void DrawHorizontal(Graphics g)
        {
            double num = Math.Floor((double) ((this.curValue - (this.scaleRange / 2.0)) / this.largeTicksDistance)) * this.largeTicksDistance;
            float x = (float) Math.Floor((double) (this.Wm - ((((double) this.W) / this.scaleRange) * (this.curValue - num))));
            Pen pen = new Pen(this.ForeColor);
            Brush brush = new SolidBrush(this.ForeColor);
            for (int i = 0; i <= this.largeTicksCount; i++)
            {
                g.DrawLine(pen, x - 0f, 0f, x - 0f, (float) this.largeTicksLength);
                g.DrawLine(pen, x - 1f, 0f, x - 1f, (float) this.largeTicksLength);
                StringFormat format = new StringFormat();
                format.Alignment = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;
                g.DrawString(Math.Round(num, 2).ToString(), this.Font, brush, new PointF(x, (float) ((this.H + this.largeTicksLength) / 2)), format);
                for (int j = 1; j <= this.smallTicksCount; j++)
                {
                    num += this.smallTicksDistance;
                    x += this.smallTicksPixels;
                    g.DrawLine(pen, x, 0f, x, (float) this.smallTicksLength);
                }
                num += this.smallTicksDistance;
                x += this.smallTicksPixels;
            }
            brush.Dispose();
            pen.Dispose();
            if (this.ShadowEnabled)
            {
                LinearGradientBrush brush2 = null;
                Rectangle rect = new Rectangle(0, 0, this.Wm, this.H);
                brush2 = new LinearGradientBrush(rect, Color.FromArgb(0xff, this.ShadowColor), Color.FromArgb(0, this.BackColor), 0f, true);
                g.FillRectangle(brush2, rect);
                rect = new Rectangle(this.Wm + 1, 0, this.Wm, this.H);
                brush2 = new LinearGradientBrush(rect, Color.FromArgb(0xff, this.ShadowColor), Color.FromArgb(0, this.BackColor), 180f, true);
                g.FillRectangle(brush2, rect);
                brush2.Dispose();
            }
            g.DrawLine(new Pen(this.NeedleColor), this.Wm, 0, this.Wm, this.H);
            g.DrawLine(new Pen(this.NeedleColor), this.Wm - 1, 0, this.Wm - 1, this.H);
        }

        private void DrawVertical(Graphics g)
        {
            double num = Math.Ceiling((double) ((this.curValue - (this.scaleRange / 2.0)) / this.largeTicksDistance)) * this.largeTicksDistance;
            float y = (float) Math.Ceiling((double) (this.Hm + ((((double) this.H) / this.scaleRange) * (this.curValue - num))));
            Pen pen = new Pen(this.ForeColor);
            Brush brush = new SolidBrush(this.ForeColor);
            for (int i = 0; i <= this.largeTicksCount; i++)
            {
                g.DrawLine(pen, 0f, y + 0f, (float) this.largeTicksLength, y + 0f);
                g.DrawLine(pen, 0f, y + 1f, (float) this.largeTicksLength, y + 1f);
                StringFormat format = new StringFormat();
                format.Alignment = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;
                g.DrawString(Math.Round(num, 2).ToString(), this.Font, brush, new PointF((float) ((this.W + this.largeTicksLength) / 2), y), format);
                for (int j = 1; j <= this.smallTicksCount; j++)
                {
                    num += this.smallTicksDistance;
                    y -= this.smallTicksPixels;
                    g.DrawLine(pen, 0f, y, (float) this.smallTicksLength, y);
                }
                num += this.smallTicksDistance;
                y -= this.smallTicksPixels;
            }
            brush.Dispose();
            pen.Dispose();
            if (this.ShadowEnabled)
            {
                LinearGradientBrush brush2 = null;
                Rectangle rect = new Rectangle(0, 0, this.W, this.Hm);
                brush2 = new LinearGradientBrush(rect, Color.FromArgb(0xff, this.ShadowColor), Color.FromArgb(0, this.BackColor), 90f, true);
                g.FillRectangle(brush2, rect);
                rect = new Rectangle(0, this.Hm + 1, this.W, this.Hm);
                brush2 = new LinearGradientBrush(rect, Color.FromArgb(0xff, this.ShadowColor), Color.FromArgb(0, this.BackColor), 270f, true);
                g.FillRectangle(brush2, rect);
                brush2.Dispose();
            }
            g.DrawLine(new Pen(this.NeedleColor), 0, this.Hm, this.W, this.Hm);
            g.DrawLine(new Pen(this.NeedleColor), 0, this.Hm + 1, this.W, this.Hm + 1);
        }

        private void InitColors()
        {
            this.BackColor = this._palette.ColorTable.ToolStripGradientBegin;
            this.BorderColor = this._palette.ColorTable.GripDark;
            this.ForeColor = this._palette.ColorTable.StatusStripText;
            if (this.NeedleKryptonColor)
            {
                this.needleColor = this._palette.ColorTable.ButtonSelectedGradientEnd;
            }
            this.ShadowColor = this._palette.ColorTable.ToolStripGradientEnd;
        }

        private void InitializeComponent()
        {
            base.SuspendLayout();
            base.Name = "SlidingScale";
            base.Size = new Size(0xfe, 40);
            base.ResumeLayout(false);
        }

        private void OnGlobalPaletteChanged(object sender, EventArgs e)
        {
            if (this._palette != null)
            {
                this._palette.PalettePaint -= new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
            }
            this._palette = KryptonManager.CurrentGlobalPalette;
            this._paletteRedirect.Target = this._palette;
            if (this._palette != null)
            {
                this._palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
                this.InitColors();
            }
            base.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (base.Visible && base.IsHandleCreated)
            {
                e.Graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
                this.CalculateLocals();
                if (this.Orientation == System.Windows.Forms.Orientation.Horizontal)
                {
                    this.DrawHorizontal(e.Graphics);
                }
                else
                {
                    this.DrawVertical(e.Graphics);
                }
                if (this.useKryptonBorder)
                {
                    base.BorderStyle = BorderStyle.None;
                    Pen pen = new Pen(this.BorderColor);
                    Rectangle clipRectangle = e.ClipRectangle;
                    clipRectangle.Height = e.ClipRectangle.Height - 1;
                    clipRectangle.Width = e.ClipRectangle.Width - 1;
                    e.Graphics.DrawRectangle(pen, clipRectangle);
                    pen.Dispose();
                }
                base.OnPaint(e);
            }
        }

        private void OnPalettePaint(object sender, PaletteLayoutEventArgs e)
        {
            base.Invalidate();
        }

        [Category("Appearance"), DefaultValue(typeof(Color), "Blue"), Browsable(true), Description("The color of the border.")]
        public Color BorderColor
        {
            get
            {
                return this.borderColor;
            }
            set
            {
                if (value != this.borderColor)
                {
                    this.borderColor = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(int), "5"), Browsable(true), Category("Appearance"), Description("The number of large ticks.")]
        public int LargeTicksCount
        {
            get
            {
                return this.largeTicksCount;
            }
            set
            {
                if ((value != this.largeTicksCount) && (value > 0))
                {
                    this.largeTicksCount = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(int), "15"), Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Category("Appearance"), Description("The length of large ticks.")]
        public int LargeTicksLength
        {
            get
            {
                return this.largeTicksLength;
            }
            set
            {
                if ((value != this.largeTicksLength) && (value > -1))
                {
                    this.largeTicksLength = value;
                    base.Invalidate();
                }
            }
        }

        [Description("The color of the scala needle."), Browsable(true), DefaultValue(typeof(Color), "Blue"), Category("Appearance")]
        public Color NeedleColor
        {
            get
            {
                return this.needleColor;
            }
            set
            {
                if (value != this.needleColor)
                {
                    this.needleColor = value;
                    base.Invalidate();
                }
            }
        }

        [Browsable(true), DefaultValue(typeof(bool), "False"), Category("Appearance"), Description("The using of the Krypton color for the scala needle.")]
        public bool NeedleKryptonColor
        {
            get
            {
                return this.needleKryptonColor;
            }
            set
            {
                if (value != this.needleKryptonColor)
                {
                    this.needleKryptonColor = value;
                    this.InitColors();
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(System.Windows.Forms.Orientation), "Horizontal"), Category("Appearance"), Browsable(true), Description("The orientation of the control."), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public System.Windows.Forms.Orientation Orientation
        {
            get
            {
                return this.orientation;
            }
            set
            {
                if (value != this.orientation)
                {
                    this.orientation = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(double), "100.0"), Browsable(true), Category("Appearance"), Description("The visible range of the scale.")]
        public double ScaleRange
        {
            get
            {
                return this.scaleRange;
            }
            set
            {
                if (value > 0.001)
                {
                    this.scaleRange = value;
                    base.Invalidate();
                }
            }
        }

        [Description("The shadow color of the component."), Category("Appearance"), Browsable(true), DefaultValue(typeof(Color), "Black")]
        public Color ShadowColor
        {
            get
            {
                return this.shadowColor;
            }
            set
            {
                if (value != this.shadowColor)
                {
                    this.shadowColor = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(bool), "true"), Description("Is the shadow enabled?"), Category("Appearance"), Browsable(true)]
        public bool ShadowEnabled
        {
            get
            {
                return this.shadowEnabled;
            }
            set
            {
                if (value != this.shadowEnabled)
                {
                    this.shadowEnabled = value;
                    base.Invalidate();
                }
            }
        }

        [Browsable(true), Category("Appearance"), Description("The number of small ticks."), DefaultValue(typeof(int), "4")]
        public int SmallTickCount
        {
            get
            {
                return this.smallTicksCount;
            }
            set
            {
                if (((value != this.smallTicksCount) && (value > -1)) && (value < 10))
                {
                    this.smallTicksCount = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(int), "10"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Browsable(true), Category("Appearance"), Description("The length of small ticks.")]
        public int SmallTickLength
        {
            get
            {
                return this.smallTicksLength;
            }
            set
            {
                if ((value != this.smallTicksLength) && (value > -1))
                {
                    this.smallTicksLength = value;
                    base.Invalidate();
                }
            }
        }

        [Description("The using of the Krypton border."), DefaultValue(typeof(bool), "True"), Browsable(true), Category("Appearance")]
        public bool UseKryptonBorder
        {
            get
            {
                return this.useKryptonBorder;
            }
            set
            {
                if (value != this.needleKryptonColor)
                {
                    this.useKryptonBorder = value;
                    this.InitColors();
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(double), "0.0"), Browsable(true), Category("Behavior"), Description("The current position of the scale.")]
        public double Value
        {
            get
            {
                return this.curValue;
            }
            set
            {
                double curValue = this.curValue;
                this.curValue = value;
                if (Math.Abs((double) (curValue - this.curValue)) > 0.0001)
                {
                    this.Refresh();
                }
            }
        }
    }
}

